package com.wei.czz.framework.store.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.wei.czz.common.enums.CommonEnum;
import com.wei.czz.common.enums.ResultEnum;
import com.wei.czz.common.enums.store.StoreStatusEnum;
import com.wei.czz.common.exception.CzzException;
import com.wei.czz.common.po.UserPo;
import com.wei.czz.common.tool.PageDto;
import com.wei.czz.common.utils.SecurityUtils;
import com.wei.czz.common.vo.store.StoreFormVo;
import com.wei.czz.common.vo.store.StoreVo;
import com.wei.czz.framework.store.dao.StoreDao;
import com.wei.czz.framework.store.entity.StoreEntity;
import com.wei.czz.framework.store.service.StoreService;
import lombok.AllArgsConstructor;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.util.CollectionUtils;

import java.util.*;


@Service("storeService")
@AllArgsConstructor
public class StoreServiceImpl extends ServiceImpl<StoreDao, StoreEntity> implements StoreService {

    private static final Logger log = LoggerFactory.getLogger(StoreServiceImpl.class);

    @Override
    public Long saveStore(StoreVo storeVo) {
        UserPo userPo = SecurityUtils.getUser();

        Long id = storeVo.getId();
        if (Objects.nonNull(id)) {
            // 更新
            StoreEntity store = baseMapper.selectById(id);
            if (Objects.isNull(store)) {
                throw new CzzException(ResultEnum.REQUEST_FAIL.getCode(), "商店不存在");
            }
            this.buildStore(storeVo, store, false);

            int count = baseMapper.updateById(store);
            log.info("修改商店完成。count={}", count);
        } else {
            StoreEntity store = this.buildStore(storeVo, null, false);
            int count = baseMapper.insert(store);
            log.info("添加商店完成。count={}", count);
            id = store.getId();
        }
        return id;
    }

    @Override
    public Long submitStore(StoreVo storeVo) {
        // 构造商店
        StoreEntity store = this.buildStore(storeVo, null, true);

        int count = baseMapper.insert(store);
        log.info("提交商店完成。count={}", count);
        return store.getId();
    }

    @Override
    public Long modifyStore(StoreVo storeVo) {
        // 构造商店
        StoreEntity store = this.buildStore(storeVo, null, false);
        store.setStatus(StoreStatusEnum.MODIFY.getValue());

        int count = baseMapper.insert(store);
        log.info("修改提交商店完成。count={}", count);
        return store.getId();
    }


    @Override
    public Long fastSubmitStore(StoreEntity store) {
        UserPo userPo = SecurityUtils.getUser();
        Date date = new Date();

        store.setId(null)
            .setStatus(StoreStatusEnum.SUBMIT.getValue())
            .setDeleteStatus(CommonEnum.ZERO.getValue())
            .setUpdateTime(date)
            .setUpdateUser(StringUtils.EMPTY)
            .setUpdateUserId(CommonEnum.ZERO.getLongValue())
            .setCreateTime(date)
            .setCreateUser(userPo.getUsername())
            .setCreateUserId(userPo.getUserId());
        // 更新数据
        int count = baseMapper.insert(store);
        log.info("快速提交商店完成。count={}", count);
        return store.getId();
    }

    @Override
    public PageDto<StoreEntity> getStorePageList(StoreFormVo storeFormVo) {

        // mp分页
        Page<StoreEntity> page = new Page<>();

        // 分页查询
        baseMapper.queryPageList(page, storeFormVo);

        log.info("分页商店查询完成。total={} list.size={}", page.getTotal(), page.getRecords().size());

        return new PageDto<>(page);
    }

    @Override
    public Integer getUserStoreCount(Integer status) {
        Long optUserId = SecurityUtils.getUserId();
        return baseMapper.selectStoreCount(optUserId, status, CommonEnum.ZERO.getValue());
    }

    @Override
    public StoreEntity getStore(Long id) {
        // 查询
        StoreEntity store = baseMapper.selectById(id);
        if (Objects.isNull(store)) {
            log.warn("商店不存在。id={}", id);
            throw new CzzException(ResultEnum.REQUEST_FAIL.getCode(), "商店不存在");
        }
        return store;
    }

    @Override
    public List<StoreEntity> getStoreOptionStatList(List<Long> submitBusinessIdList, List<Long> modifyBusinessIdList) {
        int count = 0;
        if (CollectionUtils.isEmpty(submitBusinessIdList)) {
            submitBusinessIdList = Collections.emptyList();
            count += 1;
        }
        if (CollectionUtils.isEmpty(modifyBusinessIdList)) {
            modifyBusinessIdList = Collections.emptyList();
            count += 1;
        }
        if (count == 2) {
            log.info("提交业务主键列表 和 修改业务主键列表 均为空");
            return Collections.emptyList();
        }
        return baseMapper.selectStoreOptionStatList(submitBusinessIdList, modifyBusinessIdList,
                StoreStatusEnum.AUDIT_RETURN.getValue(), StoreStatusEnum.MODIFY_RETURN.getValue(),
                CommonEnum.ZERO.getValue());
    }

    @Override
    public List<StoreEntity> getStoreMaxFinishList(List<Long> businessIdList) {
        if (CollectionUtils.isEmpty(businessIdList)) {
            log.info("传入业务主键列表为空");
            return Collections.emptyList();
        }
        return baseMapper.selectStoreMaxFinishList(businessIdList, StoreStatusEnum.FINISH.getValue(),
                CommonEnum.ZERO.getValue());
    }

    @Override
    public List<StoreEntity> getStoreList(List<Long> idList, Integer deleteStatus) {
        if (CollectionUtils.isEmpty(idList)) {
            log.info("传入商店主键列表为空");
            return Collections.emptyList();
        }
        LambdaQueryWrapper<StoreEntity> storeLambdaQueryWrapper = new LambdaQueryWrapper<>();
        // 匹配条件
        storeLambdaQueryWrapper.in(StoreEntity::getId, idList)
                .eq(Objects.nonNull(deleteStatus), StoreEntity::getDeleteStatus, deleteStatus);
        // 查询
        return baseMapper.selectList(storeLambdaQueryWrapper);
    }

    @Override
    public List<StoreEntity> getHistorySubmitList(Long businessId, Integer status) {

        if (StoreStatusEnum.SUBMIT.getValue().equals(status)) {
            /*
                获取提交记录列表
             */
            LambdaQueryWrapper<StoreEntity> storeLambdaQueryWrapper = new LambdaQueryWrapper<>();
            storeLambdaQueryWrapper.eq(StoreEntity::getBusinessId, businessId)
                    .eq(StoreEntity::getStatus, status)
                    .eq(StoreEntity::getDeleteStatus, CommonEnum.ZERO.getValue());
            // 查询
            List<StoreEntity> storeList = baseMapper.selectList(storeLambdaQueryWrapper);
            if (storeList.isEmpty()) {
                log.info("查询商店历史提交记录结果为空。businessId={} status={}", businessId, status);
            }
            return storeList;
        } else if (StoreStatusEnum.MODIFY.getValue().equals(status)) {
            /*
                获取修改记录
                1、获取商店状态（审核通过）对应的最新商店主键
                2、获取修改记录列表
             */
            Long maxId = baseMapper.selectLastId(businessId, StoreStatusEnum.FINISH.getValue(),
                    CommonEnum.ZERO.getValue());
            log.info("商店最新审核通过主键：{}", maxId);

            LambdaQueryWrapper<StoreEntity> storeLambdaQueryWrapper = new LambdaQueryWrapper<>();
            storeLambdaQueryWrapper.gt(StoreEntity::getId, maxId)
                    .eq(StoreEntity::getBusinessId, businessId)
                    .eq(StoreEntity::getStatus, status)
                    .eq(StoreEntity::getDeleteStatus, CommonEnum.ZERO.getValue());
            // 查询
            List<StoreEntity> storeList = baseMapper.selectList(storeLambdaQueryWrapper);
            if (storeList.isEmpty()) {
                log.info("查询商店历史修改记录结果为空。businessId={} status={}", businessId, status);
            }
            return storeList;
        } else {
            log.error("商店状态不满足条件。status={}", StoreStatusEnum.getName(status));
            return Collections.emptyList();
        }
    }

    @Override
    public Long getLastId(Long businessId, Integer status) {
        Long maxId = baseMapper.selectLastId(businessId, status, CommonEnum.ZERO.getValue());
        log.info("查询商店状态对应的最新商店主键完成。maxId={}", maxId);
        return maxId;
    }

    @Override
    public StoreEntity getLastFinishStore(Long businessId) {
        Long maxId = baseMapper.selectLastId(businessId, StoreStatusEnum.FINISH.getValue(), CommonEnum.ZERO.getValue());
        log.info("查询商店状态对应的最新商店主键完成。maxId={}", maxId);
        if (Objects.isNull(maxId)) {
            return null;
        }
        return this.getStore(maxId);
    }

    @Override
    public List<StoreEntity> getFinishStoreList(Long businessId) {
        if (Objects.isNull(businessId)) {
            log.info("传入的业务主键为空");
            return Collections.emptyList();
        }
        LambdaQueryWrapper<StoreEntity> storeLambdaQueryWrapper = new LambdaQueryWrapper<>();
        storeLambdaQueryWrapper.eq(StoreEntity::getBusinessId, businessId)
                .eq(StoreEntity::getStatus, StoreStatusEnum.FINISH.getValue())
                .eq(StoreEntity::getDeleteStatus, CommonEnum.ZERO.getValue());
        // 查询
        List<StoreEntity> storeList = baseMapper.selectList(storeLambdaQueryWrapper);
        if (storeList.isEmpty()) {
            log.info("查询商店审核通过数据结果为空。business={}", businessId);
        }
        return storeList;
    }

    @Override
    public int updateStore(StoreEntity store) {
        if (Objects.isNull(store.getId())) {
            log.error("传入商店主键为空，更新失败。{}", store);
            throw new CzzException();
        }
        int count = baseMapper.updateById(store);
        log.info("更新商店完成。count={}", count);
        return count;
    }

    @Override
    public void batchDeleteStore(List<Long> idList) {
        UserPo userPo = SecurityUtils.getUser();
        Date date = new Date();

        LambdaUpdateWrapper<StoreEntity> storeLambdaUpdateWrapper = new LambdaUpdateWrapper<>();
        // 设置值
        storeLambdaUpdateWrapper.set(StoreEntity::getDeleteStatus, CommonEnum.ONE.getValue())
                .set(StoreEntity::getUpdateTime, date)
                .set(StoreEntity::getUpdateUser, userPo.getUsername())
                .set(StoreEntity::getUpdateUserId, userPo.getUserId());
        // 匹配条件
        storeLambdaUpdateWrapper.in(StoreEntity::getId, idList)
                .eq(StoreEntity::getDeleteStatus, CommonEnum.ZERO.getValue());
        // 更新
        int count = baseMapper.update(null, storeLambdaUpdateWrapper);
        log.info("删除商店完成。count={}", count);
    }

    /**
     * 构建商店对象
     * @param storeVo  参数对象
     * @param store    商店对象
     * @param isSubmit 是否提交
     * @return 商店对象
     */
    private StoreEntity buildStore(StoreVo storeVo, StoreEntity store, boolean isSubmit) {
        UserPo userPo = SecurityUtils.getUser();
        Date date = new Date();
        Integer status = isSubmit ? StoreStatusEnum.SUBMIT.getValue() : StoreStatusEnum.SAVE.getValue();
        boolean isUpdate = Objects.nonNull(store);

        if (!isUpdate) {
            store = new StoreEntity();
        }
        store.setUserId(userPo.getUserId())
            .setBusinessId(storeVo.getBusinessId())
            .setName(storeVo.getName())
            .setAddressProvince(Optional.ofNullable(storeVo.getAddressProvince()).orElse(CommonEnum.MINUS_ONE.getValue()))
            .setAddressCity(Optional.ofNullable(storeVo.getAddressCity()).orElse(CommonEnum.MINUS_ONE.getValue()))
            .setAddressDistrict(Optional.ofNullable(storeVo.getAddressDistrict()).orElse(CommonEnum.MINUS_ONE.getValue()))
            .setAddressStreet(Optional.ofNullable(storeVo.getAddressStreet()).orElse(CommonEnum.MINUS_ONE.getValue()))
            .setAddress(Optional.ofNullable(storeVo.getAddress()).orElse(StringUtils.EMPTY))
            .setArea(
                    Optional.ofNullable(storeVo.getArea())
                            .map(area -> (int) (area * 100))
                            .orElse(CommonEnum.MINUS_ONE.getValue())
            )
            .setMainClass(Optional.ofNullable(storeVo.getMainClass()).orElse(CommonEnum.MINUS_ONE.getValue()))
            .setSubClass(Optional.ofNullable(storeVo.getSubClass()).orElse(CommonEnum.MINUS_ONE.getValue()))
            .setStatus(status)
            .setDeleteStatus(CommonEnum.ZERO.getValue())
            .setUpdateTime(date);
        if (isUpdate) {
            store.setUpdateUser(userPo.getUsername())
                .setUpdateUserId(userPo.getUserId());
        } else {
            store.setUpdateUser(StringUtils.EMPTY)
                .setUpdateUserId(CommonEnum.ZERO.getLongValue())
                .setCreateTime(date)
                .setCreateUser(userPo.getUsername())
                .setCreateUserId(userPo.getUserId());
        }
        return store;
    }
}